<!-- build time:Sun Nov 24 2019 22:25:19 GMT+0800 (China Standard Time) --><!DOCTYPE html><html lang="zh"><head><meta charset="utf-8"><title>OpenStack-Cinder简介 - Note?Note!</title><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="description" content="简介Cinder是一个OpenStack的组件，提供块存储服务。主要功能为：基于组件的架构高可用容错可回滚开源，标准"><meta name="keywords" content="Development,OpenStack,Cinder"><meta property="og:type" content="article"><meta property="og:title" content="OpenStack-Cinder简介"><meta property="og:url" content="http:&#x2F;&#x2F;www.borgor.cn&#x2F;2017-11-08&#x2F;4c004735.html"><meta property="og:site_name" content="Note?Note!"><meta property="og:description" content="简介Cinder是一个OpenStack的组件，提供块存储服务。主要功能为：基于组件的架构高可用容错可回滚开源，标准"><meta property="og:locale" content="zh-CN"><meta property="og:image" content="https:&#x2F;&#x2F;imgs.borgor.cn&#x2F;imgs20190625084547.png"><meta property="og:updated_time" content="2019-10-08T06:16:25.000Z"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https:&#x2F;&#x2F;imgs.borgor.cn&#x2F;imgs20190625084547.png"><link rel="icon" href="/favicon.ico"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css"><link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/font-awesome/5.4.1/css/all.min.css"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:400,600|Source+Code+Pro"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-light.min.css"><style>body>.footer,body>.navbar,body>.section{opacity:0}</style><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/1.6.8/css/lightgallery.min.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/justifiedGallery/3.7.0/css/justifiedGallery.min.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/outdated-browser/1.1.5/outdatedbrowser.min.css"><link rel="stylesheet" href="/css/back-to-top.css"><script>var _hmt=_hmt||[];!function(){var e=document.createElement("script");e.src="//hm.baidu.com/hm.js?6cecff6d18ae0c22fd7ac294c80fe7c0";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(e,c)}()</script><link rel="stylesheet" href="/css/progressbar.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js"></script><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><link rel="stylesheet" href="/css/style.css"></head><body class="is-2-column"><nav class="navbar navbar-main"><div class="container"><div class="navbar-brand is-flex-center"><a class="navbar-item navbar-logo" href="/"><img src="https://imgs.borgor.cn/imgs20190625111723.jpg" alt="OpenStack-Cinder简介" height="28"></a></div><div class="navbar-menu"><div class="navbar-start"><a class="navbar-item" href="/">首页</a> <a class="navbar-item" href="/archives">归档</a> <a class="navbar-item" href="/categories">分类</a> <a class="navbar-item" href="/tags">标签</a> <a class="navbar-item" href="/readinglist">书单</a></div><div class="navbar-end"><a class="navbar-item is-hidden-tablet catalogue" title="目录" href="javascript:;" target="_blank" rel="noopener"><i class="fas fa-list-ul"></i> </a><a class="navbar-item search" title="搜索" href="javascript:;" target="_blank" rel="noopener"><i class="fas fa-search"></i></a></div></div></div></nav><section class="section"><div class="container"><div class="columns"><div class="column is-8-tablet is-9-desktop is-9-widescreen has-order-2 column-main"><div class="card"><div class="card-image"><span class="image is-7by1"><img class="thumbnail" src="https://imgs.borgor.cn/imgs20190625084547.png" alt="OpenStack-Cinder简介"></span></div><div class="card-content article"><div class="level article-meta is-size-7 is-uppercase is-mobile is-overflow-x-auto"><div class="level-left"><time class="level-item has-text-grey" datetime="2017-11-08T02:18:51.000Z">2017-11-08</time><div class="level-item"><a class="has-link-grey -link" href="/categories/Operations/">Operations</a>&nbsp;/&nbsp;<a class="has-link-grey -link" href="/categories/Operations/OpenStack/">OpenStack</a></div><span class="level-item has-text-grey">23 分钟 读完 (大约 3484 个字) </span><span class="level-item has-text-grey" id="busuanzi_container_page_pv"><i class="far fa-eye"></i> <span id="busuanzi_value_page_pv">0</span>次访问</span></div></div><h1 class="title is-size-3 is-size-4-mobile has-text-weight-normal">OpenStack-Cinder简介</h1><div class="content"><h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p><strong>Cinder是一个OpenStack的组件，提供块存储服务。主要功能为</strong>：</p><ul><li>基于组件的架构</li><li>高可用</li><li>容错</li><li>可回滚</li><li>开源，标准</li></ul><a id="more"></a><p><strong>Cinder组件主要包括如下组件</strong>：</p><ul><li><strong>API service</strong>：Cinder-api 是主要服务接口, 负责接受和处理外界的API请求，并将请求放入RabbitMQ队列，交由后端执行。 Cinder目前提供Volume API V2</li><li><strong>Scheduler service</strong>: 处理任务队列的任务，并根据预定策略选择合适的Volume Service节点来执行任务。目前版本的cinder仅仅提供了一个Simple Scheduler, 该调度器选择卷数量最少的一个活跃节点来创建卷。</li><li><strong>Volume service</strong>: 该服务运行在存储节点上，管理存储空间，塔处理cinder数据库的维护状态的读写请求，通过消息队列和直接在块存储设备或软件上与其他进程交互。每个存储节点都有一个Volume Service，若干个这样的存储节点联合起来可以构成一个存储资源池。</li><li><strong>cinder-backup</strong> – Provides a means to back up a Cinder Volume to various backup targets.</li><li>为了支持不同类型和型号的存储，当前版本的Cinder为Volume Service如下drivers。当然在Cinder的blueprints当中还有一些其它的drivers，以后的版本可能会添加进来。<ul><li><strong>本地存储</strong> ： <em>LVM, Sheepdog</em></li><li><strong>网络存储</strong> ： <em>NFS, RBD (RADOS)</em></li><li><strong>IBM</strong> : <em>XIV, Storwize V7000， SVC storage systems</em></li><li><strong>Netapp</strong> : <em>NFS存储；ISCSI存储则需要OnCommand 5.0和Data ONTAP 7-mode storage systems with installed iSCSI licenses</em></li><li><strong>EMC</strong> : <em>VNX, VMAX/VMAXe</em></li><li><strong>Solidfire</strong> : <em>Solidfire cluster</em></li></ul></li></ul><h2 id="Cinder-架构"><a href="#Cinder-架构" class="headerlink" title="Cinder 架构"></a>Cinder 架构</h2><p><img src="https://imgs.borgor.cn/imgs/imgs-OpenStack%E5%9D%97%E5%AD%98%E5%82%A8%E7%BB%84%E4%BB%B6%E7%AE%80%E4%BB%8B-2019-6-25-11-2-10.png" alt></p><ul><li><p><strong>Cinder-api</strong></p><p>Cinder-api是cinder服务的endpoint，提供rest接口，负责处理client请求，并将请求发送至对应的Message Queue。</p></li><li><p><strong>Cinder-scheduler</strong></p><p>负责cinder请求调度，其核心部分就是scheduler_driver, 作为scheduler manager的driver，负责具体的调度处理，grizzly版本的cinder-scheduler部分提供了三个scheduler driver分别是：</p><ul><li>ChanceScheduler： 随机选取cinder-volume service创建cinder volume</li><li>SimpleScheduler： 根据availability zone 和 cinder-volume service的capacity进行选择</li><li>FilterScheduler： 可以选择具体的filter规则，满足filter规则的cinder-volume service将会通过筛选，创建cinder volume</li><li>CapacityWeigher：cinder-vloume service 的可用Capacity越多，weight之越大。</li></ul></li></ul><blockquote><p>默认Cinder-Scheduler使用FilterScheduler作为调度volume service的driver。</p><p>FilterScheduler主要机制是filter 和weighting。</p><p>Filter即cinder-scheduler分析用户创建volume请求，删选cinder-volume service</p><p>目前Cinder-scheduler支持的filter包括：</p><ul><li><p>CapabilitiesFilter：根据用户创建的volume type类型筛选cinder-volume service</p></li><li><p>RetryFilter：过滤创建volume失败的cinder-volume service，在reschedule阶段起作用。</p></li><li><p>CapacityFilter：过滤可用容量不足以满足用户请求的cinder-volume service</p></li><li><p>JsonFilter：支持Json语法自定义filter规则，选择cinder-volume service</p></li><li><p>AvailabilityZoneFilter：根据cinder-volume属性AvailabilityZone选择指定Zone的cinder-volume service。 Cinder-volume service的AvailabilityZone是通过配置文件storage_availability_zone进行指定。</p></li></ul><p>使用cinder service-list可以查看cinder service所在的AvailabilityZone</p><p>Weighing即根据cinder-volume service的可用资源等情况赋予权重，目前支持的Weigher：</p></blockquote><p>cinder-volume支持的后端驱动可见：<a href="https://wiki.openstack.org/wiki/CinderSupportMatrix" target="_blank" rel="noopener">https://wiki.openstack.org/wiki/CinderSupportMatrix</a></p><h2 id="Cinder创建卷的过程"><a href="#Cinder创建卷的过程" class="headerlink" title="Cinder创建卷的过程"></a>Cinder创建卷的过程</h2><h3 id="整体流程"><a href="#整体流程" class="headerlink" title="整体流程"></a>整体流程</h3><p>创建卷涉及的答题步骤主要有以下几步：</p><ol><li>Client发送请求，通过RESTFUL接口访问cinder-api。</li><li>Api解析响应请求，api解析由Client发送来的请求，并通过rpc进一步调用cinder-scheduler。</li><li>Scheduler对资源进行调度，scheduler选择合适的节点进行。</li><li>Volume调用Driver创建卷，volume通过指定Driver进行卷的创建。</li></ol><h3 id="代码详解"><a href="#代码详解" class="headerlink" title="代码详解"></a>代码详解</h3><p>Cinder创建卷的过程是整个Cinder过程中代码覆盖量最高的，点击上图或者下载可以查改高清图。从上图可以看出，创建卷的主要过程分为Api、Scheduler、Volume三个阶段。</p><p>####Cinder-Api过程</p><ol><li><p><strong>cinder\api\v2\volumes.py</strong></p><p><em>VolumeController. create</em>函数对创建请求进行响应，首先函数对<strong>volume_type</strong>、<strong>metadata</strong>、<strong>snapshot</strong>等信息进行检查，然后调用<em>Volume API</em>的<em>create</em>进行创建。</p><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@wsgi.response(http_client.ACCEPTED)</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create</span><span class="hljs-params">(self, req, body)</span>:</span></span><br><span class="line">    <span class="hljs-string">"""Creates a new volume."""</span></span><br><span class="line">    self.assert_valid_body(body, <span class="hljs-string">'volume'</span>)</span><br><span class="line"></span><br><span class="line">    LOG.debug(<span class="hljs-string">'Create volume request body: %s'</span>, body)</span><br><span class="line">    context = req.environ[<span class="hljs-string">'cinder.context'</span>]</span><br><span class="line">    volume = body[<span class="hljs-string">'volume'</span>]</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment"># Check up front for legacy replication parameters to quick fail</span></span><br><span class="line">    source_replica = volume.get(<span class="hljs-string">'source_replica'</span>)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">if</span> source_replica:</span><br><span class="line">        msg = _(<span class="hljs-string">"Creating a volume from a replica source was part of the "</span></span><br><span class="line">                <span class="hljs-string">"replication v1 implementation which is no longer "</span></span><br><span class="line">                <span class="hljs-string">"available."</span>)</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line">    kwargs = &#123;&#125;</span><br><span class="line">    self.validate_name_and_description(volume)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment"># NOTE(thingee): v2 API allows name instead of display_name</span></span><br><span class="line">    <span class="hljs-keyword">if</span> <span class="hljs-string">'name'</span> <span class="hljs-keyword">in</span> volume:</span><br><span class="line">        volume[<span class="hljs-string">'display_name'</span>] = volume.pop(<span class="hljs-string">'name'</span>)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment"># NOTE(thingee): v2 API allows description instead of</span></span><br><span class="line">    <span class="hljs-comment">#                display_description</span></span><br><span class="line">    <span class="hljs-keyword">if</span> <span class="hljs-string">'description'</span> <span class="hljs-keyword">in</span> volume:</span><br><span class="line">        volume[<span class="hljs-string">'display_description'</span>] = volume.pop(<span class="hljs-string">'description'</span>)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">if</span> <span class="hljs-string">'image_id'</span> <span class="hljs-keyword">in</span> volume:</span><br><span class="line">        volume[<span class="hljs-string">'imageRef'</span>] = volume.pop(<span class="hljs-string">'image_id'</span>)</span><br><span class="line"></span><br><span class="line">    req_volume_type = volume.get(<span class="hljs-string">'volume_type'</span>, <span class="hljs-literal">None</span>)</span><br><span class="line">    <span class="hljs-keyword">if</span> req_volume_type:</span><br><span class="line">        <span class="hljs-comment"># Not found exception will be handled at the wsgi level</span></span><br><span class="line">        kwargs[<span class="hljs-string">'volume_type'</span>] = (</span><br><span class="line">            objects.VolumeType.get_by_name_or_id(context, req_volume_type))</span><br><span class="line"></span><br><span class="line">    kwargs[<span class="hljs-string">'metadata'</span>] = volume.get(<span class="hljs-string">'metadata'</span>, <span class="hljs-literal">None</span>)</span><br><span class="line"></span><br><span class="line">    snapshot_id = volume.get(<span class="hljs-string">'snapshot_id'</span>)</span><br><span class="line">    <span class="hljs-keyword">if</span> snapshot_id <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:</span><br><span class="line">        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> uuidutils.is_uuid_like(snapshot_id):</span><br><span class="line">            msg = _(<span class="hljs-string">"Snapshot ID must be in UUID form."</span>)</span><br><span class="line">            <span class="hljs-keyword">raise</span> exc.HTTPBadRequest(explanation=msg)</span><br><span class="line">        <span class="hljs-comment"># Not found exception will be handled at the wsgi level</span></span><br><span class="line">        kwargs[<span class="hljs-string">'snapshot'</span>] = self.volume_api.get_snapshot(context,</span><br><span class="line">                                                          snapshot_id)</span><br><span class="line">    <span class="hljs-keyword">else</span>:</span><br><span class="line">        kwargs[<span class="hljs-string">'snapshot'</span>] = <span class="hljs-literal">None</span></span><br><span class="line"></span><br><span class="line">    source_volid = volume.get(<span class="hljs-string">'source_volid'</span>)</span><br><span class="line">    <span class="hljs-keyword">if</span> source_volid <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:</span><br><span class="line">        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> uuidutils.is_uuid_like(source_volid):</span><br><span class="line">            msg = _(<span class="hljs-string">"Source volume ID '%s' must be a "</span></span><br><span class="line">                    <span class="hljs-string">"valid UUID."</span>) % source_volid</span><br><span class="line">            <span class="hljs-keyword">raise</span> exc.HTTPBadRequest(explanation=msg)</span><br><span class="line">        <span class="hljs-comment"># Not found exception will be handled at the wsgi level</span></span><br><span class="line">        kwargs[<span class="hljs-string">'source_volume'</span>] = \</span><br><span class="line">            self.volume_api.get_volume(context,</span><br><span class="line">                                       source_volid)</span><br><span class="line">    <span class="hljs-keyword">else</span>:</span><br><span class="line">        kwargs[<span class="hljs-string">'source_volume'</span>] = <span class="hljs-literal">None</span></span><br><span class="line"></span><br><span class="line">    kwargs[<span class="hljs-string">'group'</span>] = <span class="hljs-literal">None</span></span><br><span class="line">    kwargs[<span class="hljs-string">'consistencygroup'</span>] = <span class="hljs-literal">None</span></span><br><span class="line">    consistencygroup_id = volume.get(<span class="hljs-string">'consistencygroup_id'</span>)</span><br><span class="line">    <span class="hljs-keyword">if</span> consistencygroup_id <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:</span><br><span class="line">        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> uuidutils.is_uuid_like(consistencygroup_id):</span><br><span class="line">            msg = _(<span class="hljs-string">"Consistency group ID '%s' must be a "</span></span><br><span class="line">                    <span class="hljs-string">"valid UUID."</span>) % consistencygroup_id</span><br><span class="line">            <span class="hljs-keyword">raise</span> exc.HTTPBadRequest(explanation=msg)</span><br><span class="line">        <span class="hljs-comment"># Not found exception will be handled at the wsgi level</span></span><br><span class="line">        kwargs[<span class="hljs-string">'group'</span>] = self.group_api.get(context, consistencygroup_id)</span><br><span class="line"></span><br><span class="line">    size = volume.get(<span class="hljs-string">'size'</span>, <span class="hljs-literal">None</span>)</span><br><span class="line">    <span class="hljs-keyword">if</span> size <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span> <span class="hljs-keyword">and</span> kwargs[<span class="hljs-string">'snapshot'</span>] <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:</span><br><span class="line">        size = kwargs[<span class="hljs-string">'snapshot'</span>][<span class="hljs-string">'volume_size'</span>]</span><br><span class="line">    <span class="hljs-keyword">elif</span> size <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span> <span class="hljs-keyword">and</span> kwargs[<span class="hljs-string">'source_volume'</span>] <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:</span><br><span class="line">        size = kwargs[<span class="hljs-string">'source_volume'</span>][<span class="hljs-string">'size'</span>]</span><br><span class="line"></span><br><span class="line">    LOG.info(<span class="hljs-string">"Create volume of %s GB"</span>, size)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">if</span> self.ext_mgr.is_loaded(<span class="hljs-string">'os-image-create'</span>):</span><br><span class="line">        image_ref = volume.get(<span class="hljs-string">'imageRef'</span>)</span><br><span class="line">        <span class="hljs-keyword">if</span> image_ref <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:</span><br><span class="line">            image_uuid = self._image_uuid_from_ref(image_ref, context)</span><br><span class="line">            kwargs[<span class="hljs-string">'image_id'</span>] = image_uuid</span><br><span class="line"></span><br><span class="line">    kwargs[<span class="hljs-string">'availability_zone'</span>] = volume.get(<span class="hljs-string">'availability_zone'</span>, <span class="hljs-literal">None</span>)</span><br><span class="line">    kwargs[<span class="hljs-string">'scheduler_hints'</span>] = volume.get(<span class="hljs-string">'scheduler_hints'</span>, <span class="hljs-literal">None</span>)</span><br><span class="line">    kwargs[<span class="hljs-string">'multiattach'</span>] = utils.get_bool_param(<span class="hljs-string">'multiattach'</span>, volume)</span><br><span class="line"></span><br><span class="line">    new_volume = self.volume_api.create(context,</span><br><span class="line">                                        size,</span><br><span class="line">                                        volume.get(<span class="hljs-string">'display_name'</span>),</span><br><span class="line">                                        volume.get(<span class="hljs-string">'display_description'</span>),</span><br><span class="line">                                        **kwargs)</span><br><span class="line"></span><br><span class="line">    retval = self._view_builder.detail(req, new_volume)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">return</span> retval</span><br></pre></td></tr></table></figure></li><li><p><strong>cinder\volume\api.py</strong></p><p>API.create函数对source_volume、volume_type等参数进行进一步检查，并调用cinder.volume.flows.api.get_flow来创建。</p><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br></pre></td><td class="code"><pre><span class="line">context.authorize(vol_policy.CREATE_FROM_IMAGE_POLICY)</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment"># Check up front for legacy replication parameters to quick fail</span></span><br><span class="line"><span class="hljs-keyword">if</span> source_replica:</span><br><span class="line">    msg = _(<span class="hljs-string">"Creating a volume from a replica source was part of the "</span></span><br><span class="line">            <span class="hljs-string">"replication v1 implementation which is no longer "</span></span><br><span class="line">            <span class="hljs-string">"available."</span>)</span><br><span class="line">    <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment"># NOTE(jdg): we can have a create without size if we're</span></span><br><span class="line"><span class="hljs-comment"># doing a create from snap or volume.  Currently</span></span><br><span class="line"><span class="hljs-comment"># the taskflow api will handle this and pull in the</span></span><br><span class="line"><span class="hljs-comment"># size from the source.</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-comment"># NOTE(jdg): cinderclient sends in a string representation</span></span><br><span class="line"><span class="hljs-comment"># of the size value.  BUT there is a possibility that somebody</span></span><br><span class="line"><span class="hljs-comment"># could call the API directly so the is_int_like check</span></span><br><span class="line"><span class="hljs-comment"># handles both cases (string representation of true float or int).</span></span><br><span class="line"><span class="hljs-keyword">if</span> size <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> strutils.is_int_like(size) <span class="hljs-keyword">or</span> int(size) &lt;= <span class="hljs-number">0</span>):</span><br><span class="line">    msg = _(<span class="hljs-string">'Invalid volume size provided for create request: %s '</span></span><br><span class="line">            <span class="hljs-string">'(size argument must be an integer (or string '</span></span><br><span class="line">            <span class="hljs-string">'representation of an integer) and greater '</span></span><br><span class="line">            <span class="hljs-string">'than zero).'</span>) % size</span><br><span class="line">    <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">if</span> consistencygroup <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> cgsnapshot <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> source_cg):</span><br><span class="line">    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> volume_type:</span><br><span class="line">        msg = _(<span class="hljs-string">"volume_type must be provided when creating "</span></span><br><span class="line">                <span class="hljs-string">"a volume in a consistency group."</span>)</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line">    cg_voltypeids = consistencygroup.volume_type_id</span><br><span class="line">    <span class="hljs-keyword">if</span> volume_type.id <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> cg_voltypeids:</span><br><span class="line">        msg = _(<span class="hljs-string">"Invalid volume_type provided: %s (requested "</span></span><br><span class="line">                <span class="hljs-string">"type must be supported by this consistency "</span></span><br><span class="line">                <span class="hljs-string">"group)."</span>) % volume_type</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">if</span> group <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> group_snapshot <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> source_group):</span><br><span class="line">    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> volume_type:</span><br><span class="line">        msg = _(<span class="hljs-string">"volume_type must be provided when creating "</span></span><br><span class="line">                <span class="hljs-string">"a volume in a group."</span>)</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line">    vol_type_ids = [v_type.id <span class="hljs-keyword">for</span> v_type <span class="hljs-keyword">in</span> group.volume_types]</span><br><span class="line">    <span class="hljs-keyword">if</span> volume_type.id <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> vol_type_ids:</span><br><span class="line">        msg = _(<span class="hljs-string">"Invalid volume_type provided: %s (requested "</span></span><br><span class="line">                <span class="hljs-string">"type must be supported by this "</span></span><br><span class="line">                <span class="hljs-string">"group)."</span>) % volume_type</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">if</span> source_volume <span class="hljs-keyword">and</span> volume_type:</span><br><span class="line">    <span class="hljs-keyword">if</span> volume_type.id != source_volume.volume_type_id:</span><br><span class="line">        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> self._retype_is_possible(</span><br><span class="line">                context,</span><br><span class="line">                source_volume.volume_type,</span><br><span class="line">                volume_type):</span><br><span class="line">            msg = _(<span class="hljs-string">"Invalid volume_type provided: %s (requested type "</span></span><br><span class="line">                    <span class="hljs-string">"is not compatible; either match source volume, "</span></span><br><span class="line">                    <span class="hljs-string">"or omit type argument)."</span>) % volume_type.id</span><br><span class="line">            <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">if</span> snapshot <span class="hljs-keyword">and</span> volume_type:</span><br><span class="line">    <span class="hljs-keyword">if</span> volume_type.id != snapshot.volume_type_id:</span><br><span class="line">        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> self._retype_is_possible(context,</span><br><span class="line">                                        snapshot.volume.volume_type,</span><br><span class="line">                                        volume_type):</span><br><span class="line">            msg = _(<span class="hljs-string">"Invalid volume_type provided: %s (requested "</span></span><br><span class="line">                    <span class="hljs-string">"type is not compatible; recommend omitting "</span></span><br><span class="line">                    <span class="hljs-string">"the type argument)."</span>) % volume_type.id</span><br><span class="line">            <span class="hljs-keyword">raise</span> exception.InvalidInput(reason=msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment"># Determine the valid availability zones that the volume could be</span></span><br><span class="line"><span class="hljs-comment"># created in (a task in the flow will/can use this information to</span></span><br><span class="line"><span class="hljs-comment"># ensure that the availability zone requested is valid).</span></span><br><span class="line">raw_zones = self.list_availability_zones(enable_cache=<span class="hljs-literal">True</span>)</span><br><span class="line">availability_zones = set([az[<span class="hljs-string">'name'</span>] <span class="hljs-keyword">for</span> az <span class="hljs-keyword">in</span> raw_zones])</span><br><span class="line"><span class="hljs-keyword">if</span> CONF.storage_availability_zone:</span><br><span class="line">    availability_zones.add(CONF.storage_availability_zone)</span><br><span class="line"></span><br><span class="line">utils.check_metadata_properties(metadata)</span><br><span class="line"></span><br><span class="line">create_what = &#123;</span><br><span class="line">    <span class="hljs-string">'context'</span>: context,</span><br><span class="line">    <span class="hljs-string">'raw_size'</span>: size,</span><br><span class="line">    <span class="hljs-string">'name'</span>: name,</span><br><span class="line">    <span class="hljs-string">'description'</span>: description,</span><br><span class="line">    <span class="hljs-string">'snapshot'</span>: snapshot,</span><br><span class="line">    <span class="hljs-string">'image_id'</span>: image_id,</span><br><span class="line">    <span class="hljs-string">'raw_volume_type'</span>: volume_type,</span><br><span class="line">    <span class="hljs-string">'metadata'</span>: metadata <span class="hljs-keyword">or</span> &#123;&#125;,</span><br><span class="line">    <span class="hljs-string">'raw_availability_zone'</span>: availability_zone,</span><br><span class="line">    <span class="hljs-string">'source_volume'</span>: source_volume,</span><br><span class="line">    <span class="hljs-string">'scheduler_hints'</span>: scheduler_hints,</span><br><span class="line">    <span class="hljs-string">'key_manager'</span>: self.key_manager,</span><br><span class="line">    <span class="hljs-string">'optional_args'</span>: &#123;<span class="hljs-string">'is_quota_committed'</span>: <span class="hljs-literal">False</span>&#125;,</span><br><span class="line">    <span class="hljs-string">'consistencygroup'</span>: consistencygroup,</span><br><span class="line">    <span class="hljs-string">'cgsnapshot'</span>: cgsnapshot,</span><br><span class="line">    <span class="hljs-string">'multiattach'</span>: multiattach,</span><br><span class="line">    <span class="hljs-string">'group'</span>: group,</span><br><span class="line">    <span class="hljs-string">'group_snapshot'</span>: group_snapshot,</span><br><span class="line">    <span class="hljs-string">'source_group'</span>: source_group,</span><br><span class="line">&#125;</span><br><span class="line"><span class="hljs-keyword">try</span>:</span><br><span class="line">    sched_rpcapi = (self.scheduler_rpcapi <span class="hljs-keyword">if</span> (</span><br><span class="line">                    <span class="hljs-keyword">not</span> cgsnapshot <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> source_cg <span class="hljs-keyword">and</span></span><br><span class="line">                    <span class="hljs-keyword">not</span> group_snapshot <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> source_group)</span><br><span class="line">                    <span class="hljs-keyword">else</span> <span class="hljs-literal">None</span>)</span><br><span class="line">    volume_rpcapi = (self.volume_rpcapi <span class="hljs-keyword">if</span> (</span><br><span class="line">                     <span class="hljs-keyword">not</span> cgsnapshot <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> source_cg <span class="hljs-keyword">and</span></span><br><span class="line">                     <span class="hljs-keyword">not</span> group_snapshot <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> source_group)</span><br><span class="line">                     <span class="hljs-keyword">else</span> <span class="hljs-literal">None</span>)</span><br><span class="line">    flow_engine = create_volume.get_flow(self.db,</span><br><span class="line">                                         self.image_service,</span><br><span class="line">                                         availability_zones,</span><br><span class="line">                                         create_what,</span><br><span class="line">                                         sched_rpcapi,</span><br><span class="line">                                         volume_rpcapi)</span><br><span class="line"><span class="hljs-keyword">except</span> Exception:</span><br><span class="line">    msg = _(<span class="hljs-string">'Failed to create api volume flow.'</span>)</span><br><span class="line">    LOG.exception(msg)</span><br><span class="line">    <span class="hljs-keyword">raise</span> exception.CinderException(msg)</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment"># Attaching this listener will capture all of the notifications that</span></span><br><span class="line"><span class="hljs-comment"># taskflow sends out and redirect them to a more useful log for</span></span><br><span class="line"><span class="hljs-comment"># cinders debugging (or error reporting) usage.</span></span><br><span class="line"><span class="hljs-keyword">with</span> flow_utils.DynamicLogListener(flow_engine, logger=LOG):</span><br><span class="line">    <span class="hljs-keyword">try</span>:</span><br><span class="line">        flow_engine.run()</span><br><span class="line">        vref = flow_engine.storage.fetch(<span class="hljs-string">'volume'</span>)</span><br><span class="line">        <span class="hljs-comment"># NOTE(tommylikehu): If the target az is not hit,</span></span><br><span class="line">        <span class="hljs-comment"># refresh the az cache immediately.</span></span><br><span class="line">        <span class="hljs-keyword">if</span> flow_engine.storage.fetch(<span class="hljs-string">'refresh_az'</span>):</span><br><span class="line">            self.list_availability_zones(enable_cache=<span class="hljs-literal">True</span>,</span><br><span class="line">                                         refresh_cache=<span class="hljs-literal">True</span>)</span><br><span class="line">        LOG.info(<span class="hljs-string">"Create volume request issued successfully."</span>,</span><br><span class="line">                 resource=vref)</span><br><span class="line">        <span class="hljs-keyword">return</span> vref</span><br><span class="line">    <span class="hljs-keyword">except</span> exception.InvalidAvailabilityZone:</span><br><span class="line">        <span class="hljs-keyword">with</span> excutils.save_and_reraise_exception():</span><br><span class="line">            self.list_availability_zones(enable_cache=<span class="hljs-literal">True</span>,</span><br><span class="line">                                         refresh_cache=<span class="hljs-literal">True</span>)</span><br></pre></td></tr></table></figure></li><li><p><strong>cinder\volume\flows\api\create_volume.py</strong></p><p>get_flow函数检查Quata，最后创建<em>EntryCreateTask</em>及<em>VolumeCastTask</em>等任务，</p><p>其中<em>EntryCreateTask</em>会将卷的创建过程写入数据库，此时卷的状态为”creating”。</p><p><em>VolumeCastTask.excute</em>函数会调用VoumeCastTask._cast_create_volume_</p><p><em>VolumeCastTask.cast_create_volume</em>函数，如果未传入host，则会经过调度进行创建卷，通过<em>scheduler_rpcapi.create_volume</em>创建卷；如果未传入host则直接交由Volume Manager去创建卷。</p></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_flow</span><span class="hljs-params">(db_api, image_service_api, availability_zones, create_what,</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">             scheduler_rpcapi=None, volume_rpcapi=None)</span>:</span></span><br><span class="line">    <span class="hljs-string">"""Constructs and returns the api entrypoint flow.</span></span><br><span class="line"><span class="hljs-string"></span></span><br><span class="line"><span class="hljs-string">    This flow will do the following:</span></span><br><span class="line"><span class="hljs-string"></span></span><br><span class="line"><span class="hljs-string">    1. Inject keys &amp; values for dependent tasks.</span></span><br><span class="line"><span class="hljs-string">    2. Extracts and validates the input keys &amp; values.</span></span><br><span class="line"><span class="hljs-string">    3. Reserves the quota (reverts quota on any failures).</span></span><br><span class="line"><span class="hljs-string">    4. Creates the database entry.</span></span><br><span class="line"><span class="hljs-string">    5. Commits the quota.</span></span><br><span class="line"><span class="hljs-string">    6. Casts to volume manager or scheduler for further processing.</span></span><br><span class="line"><span class="hljs-string">    """</span></span><br><span class="line"></span><br><span class="line">    flow_name = ACTION.replace(<span class="hljs-string">":"</span>, <span class="hljs-string">"_"</span>) + <span class="hljs-string">"_api"</span></span><br><span class="line">    api_flow = linear_flow.Flow(flow_name)</span><br><span class="line"></span><br><span class="line">    api_flow.add(ExtractVolumeRequestTask(</span><br><span class="line">        image_service_api,</span><br><span class="line">        availability_zones,</span><br><span class="line">        rebind=&#123;<span class="hljs-string">'size'</span>: <span class="hljs-string">'raw_size'</span>,</span><br><span class="line">                <span class="hljs-string">'availability_zone'</span>: <span class="hljs-string">'raw_availability_zone'</span>,</span><br><span class="line">                <span class="hljs-string">'volume_type'</span>: <span class="hljs-string">'raw_volume_type'</span>&#125;))</span><br><span class="line">    api_flow.add(QuotaReserveTask(),</span><br><span class="line">                 EntryCreateTask(),</span><br><span class="line">                 QuotaCommitTask())</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">if</span> scheduler_rpcapi <span class="hljs-keyword">and</span> volume_rpcapi:</span><br><span class="line">        <span class="hljs-comment"># This will cast it out to either the scheduler or volume manager via</span></span><br><span class="line">        <span class="hljs-comment"># the rpc apis provided.</span></span><br><span class="line">        api_flow.add(VolumeCastTask(scheduler_rpcapi, volume_rpcapi, db_api))</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment"># Now load (but do not run) the flow using the provided initial data.</span></span><br><span class="line">    <span class="hljs-keyword">return</span> taskflow.engines.load(api_flow, store=create_what)</span><br></pre></td></tr></table></figure><h4 id="Cinder-Scheduler过程"><a href="#Cinder-Scheduler过程" class="headerlink" title="Cinder-Scheduler过程"></a>Cinder-Scheduler过程</h4><ol><li><strong>cinder\scheduler\rpcapi.py（此步还属于cinder-api）</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_volume</span><span class="hljs-params">(self, ctxt, volume, snapshot_id=None, image_id=None,</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                  request_spec=None, filter_properties=None)</span>:</span></span><br><span class="line">    volume.create_worker()</span><br><span class="line">    cctxt = self._get_cctxt()</span><br><span class="line">    msg_args = &#123;<span class="hljs-string">'snapshot_id'</span>: snapshot_id, <span class="hljs-string">'image_id'</span>: image_id,</span><br><span class="line">                <span class="hljs-string">'request_spec'</span>: request_spec,</span><br><span class="line">                <span class="hljs-string">'filter_properties'</span>: filter_properties, <span class="hljs-string">'volume'</span>: volume&#125;</span><br><span class="line">    <span class="hljs-keyword">return</span> cctxt.cast(ctxt, <span class="hljs-string">'create_volume'</span>, **msg_args)</span><br></pre></td></tr></table></figure><p>SchedulerAPI.create_volume函数会通过消息异步调用SchedulerManager.create_volume函数。</p><ol start="2"><li><strong>cinder\scheduler\manager.py</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@objects.Volume.set_workers</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_volume</span><span class="hljs-params">(self, context, volume, snapshot_id=None, image_id=None,</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                  request_spec=None, filter_properties=None)</span>:</span></span><br><span class="line">    self._wait_for_scheduler()</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">try</span>:</span><br><span class="line">        flow_engine = create_volume.get_flow(context,</span><br><span class="line">                                             self.driver,</span><br><span class="line">                                             request_spec,</span><br><span class="line">                                             filter_properties,</span><br><span class="line">                                             volume,</span><br><span class="line">                                             snapshot_id,</span><br><span class="line">                                             image_id)</span><br><span class="line">    <span class="hljs-keyword">except</span> Exception:</span><br><span class="line">        msg = _(<span class="hljs-string">"Failed to create scheduler manager volume flow"</span>)</span><br><span class="line">        LOG.exception(msg)</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.CinderException(msg)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">with</span> flow_utils.DynamicLogListener(flow_engine, logger=LOG):</span><br><span class="line">        flow_engine.run()</span><br></pre></td></tr></table></figure><p>SchedulerManager.create_volume函数，使用自己的flow来创建volume，其中还传入了Driver。</p><ol start="3"><li><strong>cinder\scheduler\flows\create_volume.py</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">execute</span><span class="hljs-params">(self, context, request_spec, filter_properties, volume)</span>:</span></span><br><span class="line">    <span class="hljs-keyword">try</span>:</span><br><span class="line">        self.driver_api.schedule_create_volume(context, request_spec,</span><br><span class="line">                                               filter_properties)</span><br><span class="line">    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:</span><br><span class="line">        self.message_api.create(</span><br><span class="line">            context,</span><br><span class="line">            message_field.Action.SCHEDULE_ALLOCATE_VOLUME,</span><br><span class="line">            resource_uuid=request_spec[<span class="hljs-string">'volume_id'</span>],</span><br><span class="line">            exception=e)</span><br><span class="line">        <span class="hljs-comment"># An error happened, notify on the scheduler queue and log that</span></span><br><span class="line">        <span class="hljs-comment"># this happened and set the volume to errored out and reraise the</span></span><br><span class="line">        <span class="hljs-comment"># error *if* exception caught isn't NoValidBackend. Otherwise *do</span></span><br><span class="line">        <span class="hljs-comment"># not* reraise (since what's the point?)</span></span><br><span class="line">        <span class="hljs-keyword">with</span> excutils.save_and_reraise_exception(</span><br><span class="line">                reraise=<span class="hljs-keyword">not</span> isinstance(e, exception.NoValidBackend)):</span><br><span class="line">            <span class="hljs-keyword">try</span>:</span><br><span class="line">                self._handle_failure(context, request_spec, e)</span><br><span class="line">            <span class="hljs-keyword">finally</span>:</span><br><span class="line">                common.error_out(volume, reason=e)</span><br></pre></td></tr></table></figure><p>get_flow函数，创建ScheduleCreateVolumeTask</p><p>ScheduleCreateVolumeTask.execute函数，会调用driver_api.schedule_create_volume</p><ol start="4"><li><strong>cinder\scheduler\filter_scheduler.py</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">schedule_create_volume</span><span class="hljs-params">(self, context, request_spec, filter_properties)</span>:</span></span><br><span class="line">    backend = self._schedule(context, request_spec, filter_properties)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> backend:</span><br><span class="line">        <span class="hljs-keyword">raise</span> exception.NoValidBackend(reason=_(<span class="hljs-string">"No weighed backends "</span></span><br><span class="line">                                                <span class="hljs-string">"available"</span>))</span><br><span class="line"></span><br><span class="line">    backend = backend.obj</span><br><span class="line">    volume_id = request_spec[<span class="hljs-string">'volume_id'</span>]</span><br><span class="line"></span><br><span class="line">    updated_volume = driver.volume_update_db(context, volume_id,</span><br><span class="line">                                             backend.host,</span><br><span class="line">                                             backend.cluster_name)</span><br><span class="line">    self._post_select_populate_filter_properties(filter_properties,</span><br><span class="line">                                                 backend)</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment"># context is not serializable</span></span><br><span class="line">    filter_properties.pop(<span class="hljs-string">'context'</span>, <span class="hljs-literal">None</span>)</span><br><span class="line"></span><br><span class="line">    self.volume_rpcapi.create_volume(context, updated_volume, request_spec,</span><br><span class="line">                                     filter_properties,</span><br><span class="line">                                     allow_reschedule=<span class="hljs-literal">True</span>)</span><br></pre></td></tr></table></figure><p>FilterScheduler. schedule_create_volume函数，更新数据库，最后通过消息队列请求调用volume_rpcapi.create_volume。</p><h4 id="Cinder-Volume过程"><a href="#Cinder-Volume过程" class="headerlink" title="Cinder-Volume过程"></a>Cinder-Volume过程</h4><ol><li><strong>/cinder/volume/rpcapi.py（此步还属于cinder-scheduler）</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_volume</span><span class="hljs-params">(self, ctxt, volume, request_spec, filter_properties,</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                  allow_reschedule=True)</span>:</span></span><br><span class="line">    cctxt = self._get_cctxt(volume.service_topic_queue)</span><br><span class="line">    cctxt.cast(ctxt, <span class="hljs-string">'create_volume'</span>,</span><br><span class="line">               request_spec=request_spec,</span><br><span class="line">               filter_properties=filter_properties,</span><br><span class="line">               allow_reschedule=allow_reschedule,</span><br><span class="line">               volume=volume)</span><br></pre></td></tr></table></figure><p>VolumeAPI.create_volume会通过消息队列远程调用VolumeManager.create_volume</p><ol start="2"><li><strong>/cinder/volume/manager.py</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_run_flow</span><span class="hljs-params">()</span>:</span></span><br><span class="line">    <span class="hljs-comment"># This code executes create volume flow. If something goes wrong,</span></span><br><span class="line">    <span class="hljs-comment"># flow reverts all job that was done and reraises an exception.</span></span><br><span class="line">    <span class="hljs-comment"># Otherwise, all data that was generated by flow becomes available</span></span><br><span class="line">    <span class="hljs-comment"># in flow engine's storage.</span></span><br><span class="line">    <span class="hljs-keyword">with</span> flow_utils.DynamicLogListener(flow_engine, logger=LOG):</span><br><span class="line">        flow_engine.run()</span><br></pre></td></tr></table></figure><p>​ VolumeManager函数也使用flow来创建volume，执行CreateVolumeFromSpecTask这个任务</p><ol start="3"><li><strong>/cinder/volume/flows/manager/create_volume.py</strong></li></ol><figure class="highlight python hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">execute</span><span class="hljs-params">(self, context, volume, volume_spec)</span>:</span></span><br><span class="line"></span><br><span class="line">    new_status = self.status_translation.get(volume_spec.get(<span class="hljs-string">'status'</span>),</span><br><span class="line">                                             <span class="hljs-string">'available'</span>)</span><br><span class="line">    update = &#123;</span><br><span class="line">        <span class="hljs-string">'status'</span>: new_status,</span><br><span class="line">        <span class="hljs-string">'launched_at'</span>: timeutils.utcnow(),</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="hljs-keyword">try</span>:</span><br><span class="line">        <span class="hljs-comment"># TODO(harlowja): is it acceptable to only log if this fails??</span></span><br><span class="line">        <span class="hljs-comment"># or are there other side-effects that this will cause if the</span></span><br><span class="line">        <span class="hljs-comment"># status isn't updated correctly (aka it will likely be stuck in</span></span><br><span class="line">        <span class="hljs-comment"># 'creating' if this fails)??</span></span><br><span class="line">        volume.update(update)</span><br><span class="line">        volume.save()</span><br><span class="line">        <span class="hljs-comment"># Now use the parent to notify.</span></span><br><span class="line">        super(CreateVolumeOnFinishTask, self).execute(context, volume)</span><br><span class="line">    <span class="hljs-keyword">except</span> exception.CinderException:</span><br><span class="line">        LOG.exception(<span class="hljs-string">"Failed updating volume %(volume_id)s with "</span></span><br><span class="line">                      <span class="hljs-string">"%(update)s"</span>, &#123;<span class="hljs-string">'volume_id'</span>: volume.id,</span><br><span class="line">                                     <span class="hljs-string">'update'</span>: update&#125;)</span><br><span class="line">    <span class="hljs-comment"># Even if the update fails, the volume is ready.</span></span><br><span class="line">    LOG.info(<span class="hljs-string">"Volume %(volume_name)s (%(volume_id)s): "</span></span><br><span class="line">             <span class="hljs-string">"created successfully"</span>,</span><br><span class="line">             &#123;<span class="hljs-string">'volume_name'</span>: volume_spec[<span class="hljs-string">'volume_name'</span>],</span><br><span class="line">              <span class="hljs-string">'volume_id'</span>: volume.id&#125;)</span><br></pre></td></tr></table></figure><p>​ CreateVolumeFromSpecTask.excute，这个函数会根据创建的不同类别，去创建卷，例如调用create_raw_volume，最终会调用具体的driver进行卷的创建。</p><p>​ 在完成创卷后，CreateVolumeOnFinishTask这个任务，启动更新数据库，将卷更新为available状态。</p><p>​ 我们可以看到在创建卷的过程中盘的状态会从“creating”状态变为“available”状态。</p><div><h1>推荐文章<span style="font-size:.45em;color:gray">（由<a href="https://github.com/huiwang/hexo-recommended-posts" target="_blank" rel="noopener">hexo文章推荐插件</a>驱动）</span></h1><ul><li><a href="http://www.borgor.cn/2019-07-05/8761a3c5.html">在Python中将字典转换为对象</a></li><li><a href="http://www.borgor.cn/2019-07-04/e47f8b8b.html">DevOps基本术语和概念</a></li><li><a href="http://www.borgor.cn/2018-07-10/85ee5d93.html">OpenStack组件介绍</a></li></ul></div><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kity@2.0.4/dist/kity.min.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kityminder-core@1.4.50/dist/kityminder.core.min.js"></script><script defer type="text/javascript" src="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.css"></div><div class="level is-size-7 is-uppercase"><div class="level-start"><div class="level-item"><span class="is-size-6 has-text-grey has-mr-7">#</span> <a class="has-link-grey -link" href="/tags/Cinder/" rel="tag">Cinder</a>, <a class="has-link-grey -link" href="/tags/Development/" rel="tag">Development</a>, <a class="has-link-grey -link" href="/tags/OpenStack/" rel="tag">OpenStack</a></div></div></div></div></div><div class="card"><div class="card-content"><h3 class="menu-label has-text-centered">喜欢这篇文章？打赏一下作者吧</h3><div class="buttons is-centered"><a class="button is-info donate"><span class="icon is-small"><i class="fab fa-alipay"></i> </span><span>支付宝</span><div class="qrcode"><img src="https://imgs.borgor.cn/imgs20190628231540.png" alt="支付宝"></div></a><a class="button is-success donate"><span class="icon is-small"><i class="fab fa-weixin"></i> </span><span>微信</span><div class="qrcode"><img src="https://imgs.borgor.cn/imgs20190628231554.png" alt="微信"></div></a></div></div></div><div class="card card-transparent"><div class="level post-navigation is-flex-wrap is-mobile"><div class="level-start"><a class="level level-item has-link-grey article-nav-prev" href="/2017-12-10/9b4e21b8.html"><i class="level-item fas fa-chevron-left"></i> <span class="level-item">Windows 与 Mac 添加静态路由</span></a></div><div class="level-end"><a class="level level-item has-link-grey article-nav-next" href="/2017-11-04/1dcf0b5d.html"><span class="level-item">OpenStackClient的使用</span> <i class="level-item fas fa-chevron-right"></i></a></div></div></div><div class="card"><div class="card-content"><h3 class="title is-5 has-text-weight-normal">评论</h3><div id="valine-thread" class="content"></div><script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script><script src="//unpkg.com/valine/dist/Valine.min.js"></script><script>new Valine({el:"#valine-thread",notify:!1,verify:!1,app_id:"ybhyfHG9S4TQhIvstdj5pprw-gzGzoHsz",app_key:"ob8A13IBceQXqd8g92nUgNMx",placeholder:"你有想说的么？"})</script></div></div></div><div class="column is-4-tablet is-3-desktop is-3-widescreen has-order-1 column-left"><div class="card widget"><div class="card-content"><nav class="level"><div class="level-item has-text-centered"><div><figure class="image is-128x128 has-mb-6"><img class="is-rounded" src="https://imgs.borgor.cn/imgs20190625111723.jpg" alt="BorGor"></figure><p class="is-size-4 is-block">BorGor</p><p class="is-size-6 is-block">Note?Note!</p><p class="is-size-6 is-flex is-flex-center has-text-grey"><i class="fas fa-map-marker-alt has-mr-7"></i> <span>Lanzhou.Gansu</span></p></div></div></nav><nav class="level is-mobile"><div class="level-item has-text-centered is-marginless"><div><p class="heading">文章</p><p class="title has-text-weight-normal">86</p></div></div><div class="level-item has-text-centered is-marginless"><div><p class="heading">分类</p><p class="title has-text-weight-normal">26</p></div></div><div class="level-item has-text-centered is-marginless"><div><p class="heading">标签</p><p class="title has-text-weight-normal">153</p></div></div></nav><div class="level"><a class="level-item button is-link is-rounded" href="/" target="_blank">关注我</a></div><div class="level is-mobile"><a class="level-item button is-white is-marginless" target="_blank" title="Github" href="https://github.com/cyrusky"><i class="fab fa-github"></i></a></div></div></div><div class="card widget" id="toc"><div class="card-content"><div class="menu"><h3 class="menu-label">目录</h3><ul class="menu-list"><ul class="menu-list"><li><a class="is-flex" href="#简介"><span class="has-mr-6">1.1</span> <span>简介</span></a></li><li><a class="is-flex" href="#Cinder-架构"><span class="has-mr-6">1.2</span> <span>Cinder 架构</span></a></li><li><a class="is-flex" href="#Cinder创建卷的过程"><span class="has-mr-6">1.3</span> <span>Cinder创建卷的过程</span></a><ul class="menu-list"><li><a class="is-flex" href="#整体流程"><span class="has-mr-6">1.3.1</span> <span>整体流程</span></a></li><li><a class="is-flex" href="#代码详解"><span class="has-mr-6">1.3.2</span> <span>代码详解</span></a></li></ul></li></ul><li><a class="is-flex" href="#undefined"><span class="has-mr-6">2</span> <span>推荐文章（由hexo文章推荐插件驱动）</span></a></li></ul></div></div></div><div class="card widget"><div class="card-content"><div class="menu"><h3 class="menu-label">分类</h3><ul class="menu-list"><li><a class="level is-marginless" href="/categories/AI/"><span class="level-start"><span class="level-item">AI</span> </span><span class="level-end"><span class="level-item tag">20</span></span></a><ul><li><a class="level is-marginless" href="/categories/AI/Machine-Learning/"><span class="level-start"><span class="level-item">Machine Learning</span> </span><span class="level-end"><span class="level-item tag">6</span></span></a></li><li><a class="level is-marginless" href="/categories/AI/Mathematics/"><span class="level-start"><span class="level-item">Mathematics</span> </span><span class="level-end"><span class="level-item tag">9</span></span></a></li><li><a class="level is-marginless" href="/categories/AI/NLP/"><span class="level-start"><span class="level-item">NLP</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-marginless" href="/categories/AI/%E5%85%AC%E5%BC%8F%E6%8E%A8%E5%AF%BC/"><span class="level-start"><span class="level-item">公式推导</span> </span><span class="level-end"><span class="level-item tag">4</span></span></a></li></ul></li><li><a class="level is-marginless" href="/categories/CheatSheets/"><span class="level-start"><span class="level-item">CheatSheets</span> </span><span class="level-end"><span class="level-item tag">4</span></span></a></li><li><a class="level is-marginless" href="/categories/DevOps/"><span class="level-start"><span class="level-item">DevOps</span> </span><span class="level-end"><span class="level-item tag">8</span></span></a><ul><li><a class="level is-marginless" href="/categories/DevOps/Anti-patterns/"><span class="level-start"><span class="level-item">Anti-patterns</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-marginless" href="/categories/DevOps/Concept/"><span class="level-start"><span class="level-item">Concept</span> </span><span class="level-end"><span class="level-item tag">3</span></span></a></li><li><a class="level is-marginless" href="/categories/DevOps/Continuous-Delivery/"><span class="level-start"><span class="level-item">Continuous Delivery</span> </span><span class="level-end"><span class="level-item tag">2</span></span></a></li><li><a class="level is-marginless" href="/categories/DevOps/TeamWorks/"><span class="level-start"><span class="level-item">TeamWorks</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-marginless" href="/categories/DevOps/Testing/"><span class="level-start"><span class="level-item">Testing</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li></ul></li><li><a class="level is-marginless" href="/categories/Development/"><span class="level-start"><span class="level-item">Development</span> </span><span class="level-end"><span class="level-item tag">33</span></span></a><ul><li><a class="level is-marginless" href="/categories/Development/Integrated/"><span class="level-start"><span class="level-item">Integrated</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-marginless" href="/categories/Development/JavaScript/"><span class="level-start"><span class="level-item">JavaScript</span> </span><span class="level-end"><span class="level-item tag">18</span></span></a></li><li><a class="level is-marginless" href="/categories/Development/Native/"><span class="level-start"><span class="level-item">Native</span> </span><span class="level-end"><span class="level-item tag">2</span></span></a></li><li><a class="level is-marginless" href="/categories/Development/Python/"><span class="level-start"><span class="level-item">Python</span> </span><span class="level-end"><span class="level-item tag">9</span></span></a></li><li><a class="level is-marginless" href="/categories/Development/React/"><span class="level-start"><span class="level-item">React</span> </span><span class="level-end"><span class="level-item tag">2</span></span></a></li><li><a class="level is-marginless" href="/categories/Development/html5/"><span class="level-start"><span class="level-item">html5</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li></ul></li><li><a class="level is-marginless" href="/categories/Operations/"><span class="level-start"><span class="level-item">Operations</span> </span><span class="level-end"><span class="level-item tag">18</span></span></a><ul><li><a class="level is-marginless" href="/categories/Operations/Nginx/"><span class="level-start"><span class="level-item">Nginx</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-marginless" href="/categories/Operations/OpenStack/"><span class="level-start"><span class="level-item">OpenStack</span> </span><span class="level-end"><span class="level-item tag">14</span></span></a></li><li><a class="level is-marginless" href="/categories/Operations/System/"><span class="level-start"><span class="level-item">System</span> </span><span class="level-end"><span class="level-item tag">3</span></span></a></li></ul></li><li><a class="level is-marginless" href="/categories/Reading-Writing/"><span class="level-start"><span class="level-item">Reading&Writing</span> </span><span class="level-end"><span class="level-item tag">3</span></span></a><ul><li><a class="level is-marginless" href="/categories/Reading-Writing/Hexo/"><span class="level-start"><span class="level-item">Hexo</span> </span><span class="level-end"><span class="level-item tag">2</span></span></a></li><li><a class="level is-marginless" href="/categories/Reading-Writing/LaTeX/"><span class="level-start"><span class="level-item">LaTeX</span> </span><span class="level-end"><span class="level-item tag">1</span></span></a></li></ul></li></ul></div></div></div><div class="card widget"><div class="card-content"><h3 class="menu-label">标签云</h3><a href="/tags/Agile/" style="font-size:10px">Agile</a> <a href="/tags/Angularjs/" style="font-size:11.11px">Angularjs</a> <a href="/tags/Animation/" style="font-size:10px">Animation</a> <a href="/tags/Application/" style="font-size:10px">Application</a> <a href="/tags/Artificial-Intelligence/" style="font-size:10px">Artificial Intelligence</a> <a href="/tags/BP/" style="font-size:10px">BP</a> <a href="/tags/Bokeh/" style="font-size:10px">Bokeh</a> <a href="/tags/Book/" style="font-size:10px">Book</a> <a href="/tags/C4-5/" style="font-size:10px">C4.5</a> <a href="/tags/CART/" style="font-size:10px">CART</a> <a href="/tags/CD/" style="font-size:10px">CD</a> <a href="/tags/CLI/" style="font-size:10px">CLI</a> <a href="/tags/CSS/" style="font-size:10px">CSS</a> <a href="/tags/CentOS/" style="font-size:11.11px">CentOS</a> <a href="/tags/Cinder/" style="font-size:10px">Cinder</a> <a href="/tags/Clipboardjs/" style="font-size:10px">Clipboardjs</a> <a href="/tags/Concept/" style="font-size:10px">Concept</a> <a href="/tags/Continuous-Delivery/" style="font-size:10px">Continuous Delivery</a> <a href="/tags/DeepLearning/" style="font-size:16.67px">DeepLearning</a> <a href="/tags/Department/" style="font-size:11.11px">Department</a> <a href="/tags/DevOps/" style="font-size:17.78px">DevOps</a> <a href="/tags/Develop/" style="font-size:13.33px">Develop</a> <a href="/tags/Development/" style="font-size:20px">Development</a> <a href="/tags/Directive/" style="font-size:10px">Directive</a> <a href="/tags/Distribution/" style="font-size:10px">Distribution</a> <a href="/tags/Django/" style="font-size:12.22px">Django</a> <a href="/tags/Document/" style="font-size:10px">Document</a> <a href="/tags/ES5/" style="font-size:10px">ES5</a> <a href="/tags/ES6/" style="font-size:10px">ES6</a> <a href="/tags/Echarts/" style="font-size:10px">Echarts</a> <a href="/tags/Engine/" style="font-size:10px">Engine</a> <a href="/tags/Entropy/" style="font-size:10px">Entropy</a> <a href="/tags/Filter/" style="font-size:10px">Filter</a> <a href="/tags/Front-End/" style="font-size:10px">Front End</a> <a href="/tags/Gallery/" style="font-size:10px">Gallery</a> <a href="/tags/Git/" style="font-size:10px">Git</a> <a href="/tags/Gradient-descent/" style="font-size:10px">Gradient descent</a> <a href="/tags/Hexo/" style="font-size:12.22px">Hexo</a> <a href="/tags/Horizon/" style="font-size:10px">Horizon</a> <a href="/tags/ID3-5/" style="font-size:10px">ID3.5</a> <a href="/tags/Icarus/" style="font-size:10px">Icarus</a> <a href="/tags/JavaScript/" style="font-size:18.89px">JavaScript</a> <a href="/tags/Javascript/" style="font-size:11.11px">Javascript</a> <a href="/tags/KVM/" style="font-size:10px">KVM</a> <a href="/tags/LaTeX/" style="font-size:10px">LaTeX</a> <a href="/tags/LibreOffice/" style="font-size:10px">LibreOffice</a> <a href="/tags/Linux/" style="font-size:10px">Linux</a> <a href="/tags/Machine-Learning/" style="font-size:11.11px">Machine Learning</a> <a href="/tags/Matrix/" style="font-size:10px">Matrix</a> <a href="/tags/MiddleWare/" style="font-size:10px">MiddleWare</a> <a href="/tags/Module/" style="font-size:10px">Module</a> <a href="/tags/Network/" style="font-size:10px">Network</a> <a href="/tags/Nginx/" style="font-size:10px">Nginx</a> <a href="/tags/NodeJS/" style="font-size:11.11px">NodeJS</a> <a href="/tags/OOP/" style="font-size:10px">OOP</a> <a href="/tags/OpenStack/" style="font-size:17.78px">OpenStack</a> <a href="/tags/OpenStackApi/" style="font-size:14.44px">OpenStackApi</a> <a href="/tags/Operations/" style="font-size:10px">Operations</a> <a href="/tags/Oprations/" style="font-size:11.11px">Oprations</a> <a href="/tags/PDF/" style="font-size:10px">PDF</a> <a href="/tags/Pipline/" style="font-size:10px">Pipline</a> <a href="/tags/Probability/" style="font-size:12.22px">Probability</a> <a href="/tags/Python/" style="font-size:15.56px">Python</a> <a href="/tags/React/" style="font-size:11.11px">React</a> <a href="/tags/Relational-algebra/" style="font-size:10px">Relational algebra</a> <a href="/tags/Restful/" style="font-size:10px">Restful</a> <a href="/tags/Route/" style="font-size:10px">Route</a> <a href="/tags/SVD/" style="font-size:10px">SVD</a> <a href="/tags/SVM/" style="font-size:11.11px">SVM</a> <a href="/tags/Scalar/" style="font-size:10px">Scalar</a> <a href="/tags/Sigmoid/" style="font-size:10px">Sigmoid</a> <a href="/tags/Team/" style="font-size:10px">Team</a> <a href="/tags/Tempest/" style="font-size:10px">Tempest</a> <a href="/tags/Tensor/" style="font-size:10px">Tensor</a> <a href="/tags/Testing/" style="font-size:10px">Testing</a> <a href="/tags/Time/" style="font-size:10px">Time</a> <a href="/tags/TimeMachine/" style="font-size:10px">TimeMachine</a> <a href="/tags/Tips/" style="font-size:10px">Tips</a> <a href="/tags/Vector/" style="font-size:10px">Vector</a> <a href="/tags/Vmware/" style="font-size:10px">Vmware</a> <a href="/tags/Vue/" style="font-size:17.78px">Vue</a> <a href="/tags/Vuex/" style="font-size:10px">Vuex</a> <a href="/tags/WSGI/" style="font-size:10px">WSGI</a> <a href="/tags/Web/" style="font-size:10px">Web</a> <a href="/tags/Word-Cut/" style="font-size:10px">Word Cut</a> <a href="/tags/aliyun/" style="font-size:10px">aliyun</a> <a href="/tags/auth/" style="font-size:10px">auth</a> <a href="/tags/babel/" style="font-size:10px">babel</a> <a href="/tags/certbot/" style="font-size:10px">certbot</a> <a href="/tags/decision-tree/" style="font-size:10px">decision tree</a> <a href="/tags/homebrew/" style="font-size:10px">homebrew</a> <a href="/tags/jwt/" style="font-size:10px">jwt</a> <a href="/tags/keystone/" style="font-size:11.11px">keystone</a> <a href="/tags/loader/" style="font-size:10px">loader</a> <a href="/tags/mathematics/" style="font-size:11.11px">mathematics</a> <a href="/tags/migrate/" style="font-size:10px">migrate</a> <a href="/tags/openstack/" style="font-size:10px">openstack</a> <a href="/tags/pdf2html/" style="font-size:10px">pdf2html</a> <a href="/tags/pm2/" style="font-size:10px">pm2</a> <a href="/tags/singular-value-decomposition/" style="font-size:10px">singular value decomposition</a> <a href="/tags/vue-router/" style="font-size:11.11px">vue-router</a> <a href="/tags/vue-ssr/" style="font-size:10px">vue-ssr</a> <a href="/tags/webpack/" style="font-size:10px">webpack</a> <a href="/tags/%E4%BD%8E%E9%80%9A%E6%BB%A4%E6%B3%A2%E5%99%A8/" style="font-size:10px">低通滤波器</a> <a href="/tags/%E5%85%A5%E9%97%A8/" style="font-size:10px">入门</a> <a href="/tags/%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F/" style="font-size:10px">全局变量</a> <a href="/tags/%E5%85%A8%E5%B1%80%E5%AF%B9%E8%B1%A1/" style="font-size:10px">全局对象</a> <a href="/tags/%E5%85%A8%E6%A0%88/" style="font-size:10px">全栈</a> <a href="/tags/%E5%85%AC%E5%BC%8F/" style="font-size:12.22px">公式</a> <a href="/tags/%E5%86%B3%E7%AD%96%E6%A0%91/" style="font-size:10px">决策树</a> <a href="/tags/%E5%87%BD%E6%95%B0/" style="font-size:10px">函数</a> <a href="/tags/%E5%88%86%E7%B1%BB%E5%99%A8/" style="font-size:10px">分类器</a> <a href="/tags/%E5%8A%A0%E9%80%9F/" style="font-size:10px">加速</a> <a href="/tags/%E5%8C%B9%E9%85%8D%E6%BB%A4%E6%B3%A2%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/" style="font-size:10px">匹配滤波边缘检测</a> <a href="/tags/%E5%8D%B7%E7%A7%AF/" style="font-size:10px">卷积</a> <a href="/tags/%E5%8D%B7%E7%A7%AF%E6%A0%B8/" style="font-size:10px">卷积核</a> <a href="/tags/%E5%8E%9F%E5%9E%8B%E9%93%BE/" style="font-size:10px">原型链</a> <a href="/tags/%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD/" style="font-size:10px">反向传播</a> <a href="/tags/%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B/" style="font-size:10px">变量类型</a> <a href="/tags/%E5%AE%98%E6%96%B9%E7%A4%BA%E4%BE%8B/" style="font-size:10px">官方示例</a> <a href="/tags/%E5%AF%B9%E5%81%B6%E5%BD%A2%E5%BC%8F/" style="font-size:10px">对偶形式</a> <a href="/tags/%E5%AF%B9%E8%B1%A1/" style="font-size:10px">对象</a> <a href="/tags/%E5%B9%B3%E7%A7%BB%E5%92%8C%E6%9F%A5%E5%88%86%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/" style="font-size:10px">平移和查分边缘检测</a> <a href="/tags/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E4%B9%98%E5%AD%90%E6%B3%95/" style="font-size:10px">拉格朗日乘子法</a> <a href="/tags/%E6%8E%A8%E5%AF%BC/" style="font-size:12.22px">推导</a> <a href="/tags/%E6%8F%90%E4%BA%A4%E9%98%B6%E6%AE%B5/" style="font-size:10px">提交阶段</a> <a href="/tags/%E6%9C%80%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1/" style="font-size:10px">最大似然估计</a> <a href="/tags/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E4%BC%B0%E8%AE%A1/" style="font-size:10px">最小二乘估计</a> <a href="/tags/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95/" style="font-size:10px">最小二乘法</a> <a href="/tags/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF/" style="font-size:10px">朴素贝叶斯</a> <a href="/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/" style="font-size:10px">机器学习</a> <a href="/tags/%E6%9D%A1%E4%BB%B6%E6%A6%82%E7%8E%87/" style="font-size:10px">条件概率</a> <a href="/tags/%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D/" style="font-size:11.11px">梯度下降</a> <a href="/tags/%E6%A2%AF%E5%BA%A6%E6%96%B9%E5%90%91%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/" style="font-size:10px">梯度方向边缘检测</a> <a href="/tags/%E6%A6%82%E5%BF%B5/" style="font-size:10px">概念</a> <a href="/tags/%E6%A6%82%E7%8E%87/" style="font-size:10px">概率</a> <a href="/tags/%E6%B1%82%E5%AF%BC/" style="font-size:10px">求导</a> <a href="/tags/%E6%B5%81%E7%A8%8B/" style="font-size:10px">流程</a> <a href="/tags/%E7%86%B5/" style="font-size:10px">熵</a> <a href="/tags/%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/" style="font-size:10px">生命周期</a> <a href="/tags/%E7%9F%A9%E9%98%B5/" style="font-size:10px">矩阵</a> <a href="/tags/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/" style="font-size:10px">神经网络</a> <a href="/tags/%E7%A7%81%E6%9C%89%E5%AF%B9%E8%B1%A1/" style="font-size:10px">私有对象</a> <a href="/tags/%E7%B1%BB/" style="font-size:10px">类</a> <a href="/tags/%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92/" style="font-size:10px">线性回归</a> <a href="/tags/%E8%81%94%E5%90%88%E6%A6%82%E7%8E%87/" style="font-size:10px">联合概率</a> <a href="/tags/%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%88%A4%E5%AE%9A%E5%87%86%E5%88%99/" style="font-size:10px">贝叶斯判定准则</a> <a href="/tags/%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/" style="font-size:10px">边缘检测</a> <a href="/tags/%E8%BE%B9%E9%99%85%E6%A6%82%E7%8E%87/" style="font-size:10px">边际概率</a> <a href="/tags/%E9%97%AD%E5%8C%85/" style="font-size:10px">闭包</a> <a href="/tags/%E9%97%B4%E9%9A%94/" style="font-size:11.11px">间隔</a> <a href="/tags/%E9%AB%98%E6%96%AF%E5%88%86%E5%B8%83/" style="font-size:10px">高斯分布</a> <a href="/tags/%E9%AB%98%E9%80%9A%E6%BB%A4%E6%B3%A2%E5%99%A8/" style="font-size:10px">高通滤波器</a></div></div><div class="column-right-shadow"><div class="card widget"><div class="card-content"><h3 class="menu-label">最新文章</h3><article class="media"><a href="/2019-11-24/4adcf99c.html" class="media-left"><p class="image is-64x64"><img class="thumbnail" src="https://imgs.borgor.cn/imgs/20191124220507.png" alt="JavaScript闭包到底解决了什么问题？"></p></a><div class="media-content"><div class="content"><div><time class="has-text-grey is-size-7 is-uppercase" datetime="2019-11-24T12:42:13.000Z">2019-11-24</time></div><a href="/2019-11-24/4adcf99c.html" class="has-link-black-ter is-size-6">JavaScript闭包到底解决了什么问题？</a><p class="is-size-7 is-uppercase"><a class="has-link-grey -link" href="/categories/Development/">Development</a> / <a class="has-link-grey -link" href="/categories/Development/JavaScript/">JavaScript</a></p></div></div></article><article class="media"><a href="/2019-11-22/f971e187.html" class="media-left"><p class="image is-64x64"><img class="thumbnail" src="https://imgs.borgor.cn/imgs/20191122161153.png" alt="JavaScript中对象的生命周期"></p></a><div class="media-content"><div class="content"><div><time class="has-text-grey is-size-7 is-uppercase" datetime="2019-11-22T06:04:32.000Z">2019-11-22</time></div><a href="/2019-11-22/f971e187.html" class="has-link-black-ter is-size-6">JavaScript中对象的生命周期</a><p class="is-size-7 is-uppercase"><a class="has-link-grey -link" href="/categories/Development/">Development</a> / <a class="has-link-grey -link" href="/categories/Development/JavaScript/">JavaScript</a></p></div></div></article><article class="media"><a href="/2019-11-21/c07cc943.html" class="media-left"><p class="image is-64x64"><img class="thumbnail" src="https://imgs.borgor.cn/imgs/20191121175758.png" alt="React官方示例中的小游戏示例"></p></a><div class="media-content"><div class="content"><div><time class="has-text-grey is-size-7 is-uppercase" datetime="2019-11-21T09:56:03.000Z">2019-11-21</time></div><a href="/2019-11-21/c07cc943.html" class="has-link-black-ter is-size-6">React官方示例中的小游戏示例</a><p class="is-size-7 is-uppercase"><a class="has-link-grey -link" href="/categories/Development/">Development</a> / <a class="has-link-grey -link" href="/categories/Development/React/">React</a></p></div></div></article><article class="media"><a href="/2019-11-21/769edcc6.html" class="media-left"><p class="image is-64x64"><img class="thumbnail" src="https://imgs.borgor.cn/imgs/20191121141128.png" alt="JavaScript引擎的工作原理探析"></p></a><div class="media-content"><div class="content"><div><time class="has-text-grey is-size-7 is-uppercase" datetime="2019-11-21T00:30:12.000Z">2019-11-21</time></div><a href="/2019-11-21/769edcc6.html" class="has-link-black-ter is-size-6">JavaScript引擎的工作原理探析</a><p class="is-size-7 is-uppercase"><a class="has-link-grey -link" href="/categories/Development/">Development</a> / <a class="has-link-grey -link" href="/categories/Development/JavaScript/">JavaScript</a></p></div></div></article><article class="media"><a href="/2019-11-19/290f6390.html" class="media-left"><p class="image is-64x64"><img class="thumbnail" src="https://imgs.borgor.cn/imgs/20191119100237.png" alt="深入了解JavaScript中的基本变量类型"></p></a><div class="media-content"><div class="content"><div><time class="has-text-grey is-size-7 is-uppercase" datetime="2019-11-19T04:22:33.000Z">2019-11-19</time></div><a href="/2019-11-19/290f6390.html" class="has-link-black-ter is-size-6">深入了解JavaScript中的基本变量类型</a><p class="is-size-7 is-uppercase"><a class="has-link-grey -link" href="/categories/Development/">Development</a> / <a class="has-link-grey -link" href="/categories/Development/JavaScript/">JavaScript</a></p></div></div></article></div></div><div class="card widget"><div class="card-content"><div class="menu"><h3 class="menu-label">归档</h3><ul class="menu-list"><li><a class="level is-marginless" href="/archives/2019/11/"><span class="level-start"><span class="level-item">十一月 2019</span> </span><span class="level-end"><span class="level-item tag">7</span></span></a></li><li><a class="level is-marginless" href="/archives/2019/10/"><span class="level-start"><span class="level-item">十月 2019</span> </span><span class="level-end"><span class="level-item tag">8</span></span></a></li><li><a class="level is-marginless" href="/archives/2019/09/"><span class="level-start"><span class="level-item">九月 2019</span> </span><span class="level-end"><span class="level-item tag">5</span></span></a></li><li><a class="level is-marginless" href="/archives/2019/08/"><span class="level-start"><span class="level-item">八月 2019</span> </span><span class="level-end"><span class="level-item tag">13</span></span></a></li><li><a class="level is-marginless" href="/archives/2019/07/"><span class="level-start"><span class="level-item">七月 2019</span> </span><span class="level-end"><span class="level-item tag">15</span></span></a></li><li><a class="level is-marginless" href="/archives/2019/06/"><span class="level-start"><span class="level-item">六月 2019</span> </span><span class="level-end"><span class="level-item tag">11</span></span></a></li><li><a class="level is-marginless" href="/archives/2018/07/"><span class="level-start"><span class="level-item">七月 2018</span> </span><span class="level-end"><span class="level-item tag">4</span></span></a></li><li><a class="level is-marginless" href="/archives/2018/06/"><span class="level-start"><span class="level-item">六月 2018</span> </span><span class="level-end"><span class="level-item tag">3</span></span></a></li><li><a class="level is-marginless" href="/archives/2017/12/"><span class="level-start"><span class="level-item">十二月 2017</span> </span><span class="level-end"><span class="level-item tag">2</span></span></a></li><li><a class="level is-marginless" href="/archives/2017/11/"><span class="level-start"><span class="level-item">十一月 2017</span> </span><span class="level-end"><span class="level-item tag">3</span></span></a></li><li><a class="level is-marginless" href="/archives/2017/10/"><span class="level-start"><span class="level-item">十月 2017</span> </span><span class="level-end"><span class="level-item tag">5</span></span></a></li><li><a class="level is-marginless" href="/archives/2017/09/"><span class="level-start"><span class="level-item">九月 2017</span> </span><span class="level-end"><span class="level-item tag">10</span></span></a></li></ul></div></div></div><div class="card widget"><div class="card-content"><div class="menu"><h3 class="menu-label">标签</h3><div class="field is-grouped is-grouped-multiline"><div class="control"><a class="tags has-addons" href="/tags/Agile/"><span class="tag">Agile</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Angularjs/"><span class="tag">Angularjs</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Animation/"><span class="tag">Animation</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Application/"><span class="tag">Application</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Artificial-Intelligence/"><span class="tag">Artificial Intelligence</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/BP/"><span class="tag">BP</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Bokeh/"><span class="tag">Bokeh</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Book/"><span class="tag">Book</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/C4-5/"><span class="tag">C4.5</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/CART/"><span class="tag">CART</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/CD/"><span class="tag">CD</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/CLI/"><span class="tag">CLI</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/CSS/"><span class="tag">CSS</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/CentOS/"><span class="tag">CentOS</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Cinder/"><span class="tag">Cinder</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Clipboardjs/"><span class="tag">Clipboardjs</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Concept/"><span class="tag">Concept</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Continuous-Delivery/"><span class="tag">Continuous Delivery</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/DeepLearning/"><span class="tag">DeepLearning</span> <span class="tag is-grey">7</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Department/"><span class="tag">Department</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/DevOps/"><span class="tag">DevOps</span> <span class="tag is-grey">8</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Develop/"><span class="tag">Develop</span> <span class="tag is-grey">4</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Development/"><span class="tag">Development</span> <span class="tag is-grey">16</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Directive/"><span class="tag">Directive</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Distribution/"><span class="tag">Distribution</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Django/"><span class="tag">Django</span> <span class="tag is-grey">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Document/"><span class="tag">Document</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/ES5/"><span class="tag">ES5</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/ES6/"><span class="tag">ES6</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Echarts/"><span class="tag">Echarts</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Engine/"><span class="tag">Engine</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Entropy/"><span class="tag">Entropy</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Filter/"><span class="tag">Filter</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Front-End/"><span class="tag">Front End</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Gallery/"><span class="tag">Gallery</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Git/"><span class="tag">Git</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Gradient-descent/"><span class="tag">Gradient descent</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Hexo/"><span class="tag">Hexo</span> <span class="tag is-grey">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Horizon/"><span class="tag">Horizon</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/ID3-5/"><span class="tag">ID3.5</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Icarus/"><span class="tag">Icarus</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/JavaScript/"><span class="tag">JavaScript</span> <span class="tag is-grey">9</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Javascript/"><span class="tag">Javascript</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/KVM/"><span class="tag">KVM</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/LaTeX/"><span class="tag">LaTeX</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/LibreOffice/"><span class="tag">LibreOffice</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Linux/"><span class="tag">Linux</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Machine-Learning/"><span class="tag">Machine Learning</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Matrix/"><span class="tag">Matrix</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/MiddleWare/"><span class="tag">MiddleWare</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Module/"><span class="tag">Module</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Network/"><span class="tag">Network</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Nginx/"><span class="tag">Nginx</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/NodeJS/"><span class="tag">NodeJS</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/OOP/"><span class="tag">OOP</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/OpenStack/"><span class="tag">OpenStack</span> <span class="tag is-grey">8</span></a></div><div class="control"><a class="tags has-addons" href="/tags/OpenStackApi/"><span class="tag">OpenStackApi</span> <span class="tag is-grey">5</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Operations/"><span class="tag">Operations</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Oprations/"><span class="tag">Oprations</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/PDF/"><span class="tag">PDF</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Pipline/"><span class="tag">Pipline</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Probability/"><span class="tag">Probability</span> <span class="tag is-grey">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Python/"><span class="tag">Python</span> <span class="tag is-grey">6</span></a></div><div class="control"><a class="tags has-addons" href="/tags/React/"><span class="tag">React</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Relational-algebra/"><span class="tag">Relational algebra</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Restful/"><span class="tag">Restful</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Route/"><span class="tag">Route</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/SVD/"><span class="tag">SVD</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/SVM/"><span class="tag">SVM</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Scalar/"><span class="tag">Scalar</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Sigmoid/"><span class="tag">Sigmoid</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Team/"><span class="tag">Team</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Tempest/"><span class="tag">Tempest</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Tensor/"><span class="tag">Tensor</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Testing/"><span class="tag">Testing</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Time/"><span class="tag">Time</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/TimeMachine/"><span class="tag">TimeMachine</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Tips/"><span class="tag">Tips</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Vector/"><span class="tag">Vector</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Vmware/"><span class="tag">Vmware</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Vue/"><span class="tag">Vue</span> <span class="tag is-grey">8</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Vuex/"><span class="tag">Vuex</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/WSGI/"><span class="tag">WSGI</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Web/"><span class="tag">Web</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Word-Cut/"><span class="tag">Word Cut</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/aliyun/"><span class="tag">aliyun</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/auth/"><span class="tag">auth</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/babel/"><span class="tag">babel</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/certbot/"><span class="tag">certbot</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/decision-tree/"><span class="tag">decision tree</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/homebrew/"><span class="tag">homebrew</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/jwt/"><span class="tag">jwt</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/keystone/"><span class="tag">keystone</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/loader/"><span class="tag">loader</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/mathematics/"><span class="tag">mathematics</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/migrate/"><span class="tag">migrate</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/openstack/"><span class="tag">openstack</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/pdf2html/"><span class="tag">pdf2html</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/pm2/"><span class="tag">pm2</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/singular-value-decomposition/"><span class="tag">singular value decomposition</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/vue-router/"><span class="tag">vue-router</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/vue-ssr/"><span class="tag">vue-ssr</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/webpack/"><span class="tag">webpack</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E4%BD%8E%E9%80%9A%E6%BB%A4%E6%B3%A2%E5%99%A8/"><span class="tag">低通滤波器</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%85%A5%E9%97%A8/"><span class="tag">入门</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F/"><span class="tag">全局变量</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%85%A8%E5%B1%80%E5%AF%B9%E8%B1%A1/"><span class="tag">全局对象</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%85%A8%E6%A0%88/"><span class="tag">全栈</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%85%AC%E5%BC%8F/"><span class="tag">公式</span> <span class="tag is-grey">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%86%B3%E7%AD%96%E6%A0%91/"><span class="tag">决策树</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%87%BD%E6%95%B0/"><span class="tag">函数</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%88%86%E7%B1%BB%E5%99%A8/"><span class="tag">分类器</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8A%A0%E9%80%9F/"><span class="tag">加速</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8C%B9%E9%85%8D%E6%BB%A4%E6%B3%A2%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/"><span class="tag">匹配滤波边缘检测</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8D%B7%E7%A7%AF/"><span class="tag">卷积</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8D%B7%E7%A7%AF%E6%A0%B8/"><span class="tag">卷积核</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8E%9F%E5%9E%8B%E9%93%BE/"><span class="tag">原型链</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD/"><span class="tag">反向传播</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B/"><span class="tag">变量类型</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%AE%98%E6%96%B9%E7%A4%BA%E4%BE%8B/"><span class="tag">官方示例</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%AF%B9%E5%81%B6%E5%BD%A2%E5%BC%8F/"><span class="tag">对偶形式</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%AF%B9%E8%B1%A1/"><span class="tag">对象</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E5%B9%B3%E7%A7%BB%E5%92%8C%E6%9F%A5%E5%88%86%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/"><span class="tag">平移和查分边缘检测</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E4%B9%98%E5%AD%90%E6%B3%95/"><span class="tag">拉格朗日乘子法</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%8E%A8%E5%AF%BC/"><span class="tag">推导</span> <span class="tag is-grey">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%8F%90%E4%BA%A4%E9%98%B6%E6%AE%B5/"><span class="tag">提交阶段</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%9C%80%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1/"><span class="tag">最大似然估计</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E4%BC%B0%E8%AE%A1/"><span class="tag">最小二乘估计</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95/"><span class="tag">最小二乘法</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF/"><span class="tag">朴素贝叶斯</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/"><span class="tag">机器学习</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%9D%A1%E4%BB%B6%E6%A6%82%E7%8E%87/"><span class="tag">条件概率</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D/"><span class="tag">梯度下降</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%A2%AF%E5%BA%A6%E6%96%B9%E5%90%91%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/"><span class="tag">梯度方向边缘检测</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%A6%82%E5%BF%B5/"><span class="tag">概念</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%A6%82%E7%8E%87/"><span class="tag">概率</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%B1%82%E5%AF%BC/"><span class="tag">求导</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%B5%81%E7%A8%8B/"><span class="tag">流程</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%86%B5/"><span class="tag">熵</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/"><span class="tag">生命周期</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%9F%A9%E9%98%B5/"><span class="tag">矩阵</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/"><span class="tag">神经网络</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%A7%81%E6%9C%89%E5%AF%B9%E8%B1%A1/"><span class="tag">私有对象</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%B1%BB/"><span class="tag">类</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92/"><span class="tag">线性回归</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E8%81%94%E5%90%88%E6%A6%82%E7%8E%87/"><span class="tag">联合概率</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%88%A4%E5%AE%9A%E5%87%86%E5%88%99/"><span class="tag">贝叶斯判定准则</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/"><span class="tag">边缘检测</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E8%BE%B9%E9%99%85%E6%A6%82%E7%8E%87/"><span class="tag">边际概率</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E9%97%AD%E5%8C%85/"><span class="tag">闭包</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E9%97%B4%E9%9A%94/"><span class="tag">间隔</span> <span class="tag is-grey">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E9%AB%98%E6%96%AF%E5%88%86%E5%B8%83/"><span class="tag">高斯分布</span> <span class="tag is-grey">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E9%AB%98%E9%80%9A%E6%BB%A4%E6%B3%A2%E5%99%A8/"><span class="tag">高通滤波器</span> <span class="tag is-grey">1</span></a></div></div></div></div></div></div></div></div></div></section><footer class="footer"><div class="container"><div class="level"><div class="level-start has-text-centered-mobile"><a class="footer-logo is-block has-mb-6" href="/"><img src="https://imgs.borgor.cn/imgs20190625111723.jpg" alt="OpenStack-Cinder简介" height="28"></a><p class="is-size-7">&copy; 2017-2019 Cyrusky&nbsp; Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> & <a href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank">Icarus</a><br><span id="busuanzi_container_site_uv">共<span id="busuanzi_value_site_uv">0</span>个访客</span><br><a target="_blank" href="https://icp.chinaz.com/info?q=borgor.cn">陇ICP备19002255号</a></p></div><div class="level-end"><div class="field has-addons is-flex-center-mobile has-mt-5-mobile is-flex-wrap is-flex-middle"><p class="control"><a class="button is-white is-large" target="_blank" title="Creative Commons" href="https://creativecommons.org/"><i class="fab fa-creative-commons"></i></a></p><p class="control"><a class="button is-white is-large" target="_blank" title="Attribution 4.0 International" href="https://creativecommons.org/licenses/by/4.0/"><i class="fab fa-creative-commons-by"></i></a></p><p class="control"><a class="button is-white is-large" target="_blank" title="Download on GitHub" href="https://github.com/ppoffice/hexo-theme-icarus"><i class="fab fa-github"></i></a></p></div></div></div></div></footer><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script><script>moment.locale("zh-CN")</script><script src="/js/animation.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/1.6.8/js/lightgallery.min.js" defer></script><script src="https://cdnjs.cloudflare.com/ajax/libs/justifiedGallery/3.7.0/js/jquery.justifiedGallery.min.js" defer></script><script src="/js/gallery.js" defer></script><div id="outdated"><h6>Your browser is out-of-date!</h6><p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" href="http://outdatedbrowser.com/" target="_blank" rel="noopener">Update my browser now</a></p><p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p></div><script src="https://cdnjs.cloudflare.com/ajax/libs/outdated-browser/1.1.5/outdatedbrowser.min.js" defer></script><script>document.addEventListener("DOMContentLoaded",function(){outdatedBrowser({bgColor:"#f25648",color:"#ffffff",lowerThan:"flex"})})</script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML" defer></script><script>document.addEventListener("DOMContentLoaded",function(){MathJax.Hub.Config({"HTML-CSS":{matchFontHeight:!1},SVG:{matchFontHeight:!1},CommonHTML:{matchFontHeight:!1},tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]]}})})</script><a id="back-to-top" title="回到顶端" href="javascript:;" target="_blank" rel="noopener"><i class="fas fa-chevron-up"></i></a><script src="/js/back-to-top.js" defer></script><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js" defer></script><script src="/js/clipboard.js" defer></script><script src="/js/main.js" defer></script><div class="searchbox ins-search"><div class="searchbox-container ins-search-container"><div class="searchbox-input-wrapper"><input type="text" class="searchbox-input ins-search-input" placeholder="想要查找什么..."> <span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span></div><div class="searchbox-result-wrapper ins-section-wrapper"><div class="ins-section-container"></div></div></div></div><script>!function(T){var N={TRANSLATION:{POSTS:"文章",PAGES:"页面",CATEGORIES:"分类",TAGS:"标签",UNTITLED:"(无标题)"},CONTENT_URL:"/content.json"};T.INSIGHT_CONFIG=N}(window)</script><script src="/js/insight.js" defer></script><link rel="stylesheet" href="/css/search.css"><link rel="stylesheet" href="/css/insight.css"></body></html><!-- rebuild by neat -->